package com.east.sng.controller;

import com.alibaba.excel.EasyExcel;
import com.east.sng.entity.param.ChargeParam;
import com.east.sng.entity.param.ChargeSearchParam;
import com.east.sng.entity.result.ChargeInfo;
import com.east.sng.service.ChargeService;
import com.east.sng.service.CourseService;
import com.east.sng.utils.EncryptDataUtil;
import com.east.sng.utils.ValidationUtil;
import com.github.pagehelper.PageHelper;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;

/**
 * @author east
 * @date: 2021/1/3
 * @Description:
 **/
@Controller
@RequestMapping("/charge")
public class ChargeController {
    @Autowired
    private ChargeService chargeService;
    @Autowired
    private CourseService courseService;

    /**
     * 缴费信息页面跳转
     * @param pageNum
     * @param pageSize
     * @param model
     * @return
     */
    @RequiresPermissions("charge:list")
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    public String list(ChargeSearchParam params, @RequestParam(name = "pn", defaultValue = "1") Integer pageNum,
                       @RequestParam(name = "pSize", defaultValue = "5") Integer pageSize, Model model) {
        model.addAttribute("page", PageHelper.startPage(pageNum, pageSize));
        List<ChargeInfo> list = this.chargeService.findCharges(params);
        //给付款人手机号加密
        list.forEach((item)-> {
            String encryptPhone = EncryptDataUtil.encryptPhone(item.getPayerPhone());
            item.setPayerPhone(encryptPhone);
        });
        model.addAttribute("charges", list);
        model.addAttribute("courses", this.courseService.findCourseColumns());
        return "charge/list";
    }

    /**
     * 缴费信息报表页面跳转
     * @return
     */
    @RequiresPermissions("charge:report")
    @RequestMapping(value = "/report", method = RequestMethod.GET)
    public String report() {
        return "charge/report";
    }

    /**
     * 缴费添加页面跳转
     * @param model
     * @return
     */
    @RequestMapping(value = "/add", method = RequestMethod.GET)
    public String toAddCharge(Model model) {
        return "charge/add";
    }

    /**
     * 缴费信息添加
     * @param chargeParam
     * @param br
     * @return
     */
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public String addCharge(@Valid ChargeParam chargeParam, BindingResult br) {
        ValidationUtil.validateData(br);
        this.chargeService.addCharge(chargeParam);
        return "success";
    }

    /**
     * 缴费信息删除
     * @param id
     * @return
     */
    @RequiresPermissions(value = {"charge:list","charge:add"},logical = Logical.AND)
    @RequestMapping(value = "/remove", method = RequestMethod.POST)
    @ResponseBody
    public String removeCharge(Integer id) {
        return this.chargeService.removeCharge(id) ? "success" : "fail";
    }

    /**
     * 缴费信息恢复
     * @param id
     * @return
     */
    @RequiresRoles("0")
    @RequiresPermissions(value = {"charge:list","charge:add"},logical = Logical.AND)
    @RequestMapping(value = "/recover", method = RequestMethod.POST)
    @ResponseBody
    public String recoverCharge(Integer id) {
        return this.chargeService.recoverCharge(id) ? "success" : "fail";
    }

    /**
     * 缴费信息批量删除
     * @param ids
     * @return
     */
    @RequiresPermissions(value = {"charge:list","charge:add"},logical = Logical.AND)
    @RequestMapping(value = "/removes", method = RequestMethod.POST)
    @ResponseBody
    public String removeCharges(Integer[] ids) {
        return this.chargeService.batchRemoveCharges(Arrays.asList(ids)) ? "success" : "fail";
    }

    /**
     * 缴费信息批量恢复
     * @param ids
     * @return
     */
    @RequiresRoles("0")
    @RequiresPermissions(value = {"charge:list","charge:add"},logical = Logical.AND)
    @RequestMapping(value = "/recovers", method = RequestMethod.POST)
    @ResponseBody
    public String recoverCharges(Integer[] ids) {
        return this.chargeService.batchRecoverCharges(Arrays.asList(ids)) ? "success" : "fail";
    }

    /**
     * 查询缴费报表数据
     * @param startTime
     * @param endTime
     * @return
     */
    @RequiresPermissions("charge:list")
    @RequestMapping(value = "/findChargeDatas", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, List<Object>> findChargeDatas(String startTime, String endTime) {
        HashMap<String, List<Object>> map = new HashMap<>();
        ArrayList<Object> labels = new ArrayList<>();
        ArrayList<Object> datas = new ArrayList<>();
        List<Map<String, Object>> chargeDatas = this.chargeService.findChargeDatas(startTime, endTime);
        chargeDatas.forEach((item)->{
            labels.add(item.get("courseName"));
            datas.add(item.get("total"));
        });
        map.put("labels",labels);
        map.put("datas",datas);
        return map;
    }

    /**
     * 导出学生信息
     * @return
     */
    @RequiresPermissions("charge:list")
    @RequestMapping(value = "/exportChargeInfo", method = RequestMethod.POST)
    public void exportInfo(Integer[] chargeIds, HttpServletResponse response) throws Exception {
        ServletOutputStream outputStream = null;
        try {
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode("学生收费信息表", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            outputStream = response.getOutputStream();
            EasyExcel.write(outputStream, ChargeInfo.class).sheet("学生收费信息表").doWrite(this.chargeService.findChargeInfo(Arrays.asList(chargeIds)));
        } finally {
            try {
                if (outputStream != null) {
                    outputStream.flush();
                    outputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}